package com.demo.testpackage;

import com.demo.config.ThreadPoolFactory;
import com.demo.entity.TblUnitBank;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;

/**
 * @author zhiqiang
 * 模拟通过sftp下载联行信息文件
 */
@Slf4j
public class Io2 {
    private Map<String, ExecutorService> executorServiceMap = new HashMap();
    public static void main(String[] args) {
        Io2 test = new Io2();
        test.downLoadFile();
    }

    /**
     * 下载联行信息文件
     */
    public void downLoadFile() {
        String sftpPath = "/home/sftpuser/unitbank/yyyyMMdd/bankName.txt";
        String b = "20220215";
        // replace(a,b) 将a替换成b
        sftpPath.replace("yyyyMMdd", b);
        // 获取当前项目绝对路径 /Users/zhiqiang/code/demo
        System.getProperty("user.dir");
        // 获取文件的结尾 /
        System.getProperty("file.separator");
        // 联行信息字符串
        String bankInfo = null;
        BufferedReader bufferedReader = null;
        try {
            // 读取t2.txt文件
            bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream("/Users/zhiqiang/temp/bankName-mini.txt")));
            // 联行信息文件第一行为标题，不存在联行信息文件
            String firstLine = bufferedReader.readLine();
            log.info("文件第一行：" + firstLine);

            int maxNum = 1000000;
            int index = 0;
            while ((bankInfo = bufferedReader.readLine()) != null) {
                // 将字符串以 ｜ 进行分割成字符串数组
                String[] bankInfoArray = bankInfo.split("\\|");
                String unitBankNo = bankInfoArray[2];
                // 判断联行号是否存在
                if (unitBankNo == null || "".equals(unitBankNo)) {
                    log.info("文件【{}】行中行号【{}】为空，记录不合规范", bankInfo, unitBankNo);
                    continue;
                }
                // 判断字符串是否全部由数字组成
                if (!StringUtils.isNumeric(unitBankNo)) {
                    log.info("文件【{}】行中行号【{}】不是全数字组成，记录不合规范", bankInfo, unitBankNo);
                    continue;
                }
                /*
                 newInstance():弱类型,效率低,只能调用无参构造
                 new():强类型,高效率,能调用任何public构造器
                 */
                // 创建线程池
                ExecutorService executorService = ThreadPoolFactory
                        .newInstance().add(this.getClass().getName(), 20);
                // 将联行信息数组添加到集合中
                List<String[]> bankInfoList = new ArrayList<>();
                bankInfoList.add(bankInfoArray);
                //
                CountDownLatch countDownLatch = new CountDownLatch(bankInfoList.size());
                for (String[] bank : bankInfoList) {
                    String bankNo = bank[0];
                    String bankName = bank[1];
                    String unitBankNO = bank[2];
                    String unitBankName = bank[3];
                    executorService.submit(() ->
                    {
                        try {
                            this.saveUnitBank(bankNo, bankName, unitBankNO, unitBankName);
                        } catch (Exception e) {
                            log.error("作业线程执行异常【{}】", bank, e);
                        } finally {
                            countDownLatch.countDown();
                        }
                    });
                }
                if (index++ > maxNum) {
                    /**
                     * 联行文件一般在20万行内
                     * 为防止【因流无限大，导致的死循环或内存溢出】，做一个读取上限，超出上限后即退出循环
                     */
                    break;
                }
            }
        } catch (FileNotFoundException e) {
            log.error("文件目录不存在", e);
        } catch (IOException e) {
            log.error("读取文件错误", e);
        }
    }

    /**
     * 模拟将联行信息文件写入到联行信息表中
     *
     * @param bankNo
     * @param bankName
     * @param unitBankNo
     * @param unitBankName
     */
    private void saveUnitBank(String bankNo, String bankName, String unitBankNo, String unitBankName) {
        TblUnitBank tblUnitBank = new TblUnitBank(bankNo, bankName, unitBankNo, unitBankName);
        System.out.println(tblUnitBank);
    }
}
